/*******************************************************************************
* Copyright (c) 2010, 2018 西安秦晔信息科技有限公司
* Licensed under the Apache License, Version 2.0 (the "License");
*    you may not use this file except in compliance with the License.
*    You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS,
*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*    See the License for the specific language governing permissions and
*    limitations under the License.
*******************************************************************************/
package com.qinyeit.serviceapp.service.dishes.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qinyeit.serviceapp.entity.*;
import com.qinyeit.serviceapp.entity.enums.*;
import com.qinyeit.serviceapp.exception.BusinessRunTimeException;
import com.qinyeit.serviceapp.repository.branchstores.MaterialCostRepository;
import com.qinyeit.serviceapp.repository.dishes.DishesFeedRelationRepository;
import com.qinyeit.serviceapp.repository.dishes.DishesMakeRelationRepository;
import com.qinyeit.serviceapp.repository.dishes.DishesSpecificationRelationRepository;
import com.qinyeit.serviceapp.repository.materials.PurchaseSpecRepository;
import com.qinyeit.serviceapp.service.branchs.BranchDataServiceImpl;
import com.qinyeit.serviceapp.service.branchstores.MaterialCostDetailService;
import com.qinyeit.serviceapp.service.branchstores.MaterialCostService;
import com.qinyeit.serviceapp.service.dishes.*;
import com.qinyeit.serviceapp.service.materials.MaterialCategoryService;
import com.qinyeit.serviceapp.service.materials.MaterialService;
import com.qinyeit.serviceapp.service.materials.PurchaseSpecService;
import com.qinyeit.serviceapp.service.materials.impl.MaterialServiceImpl;
import com.qinyeit.serviceapp.service.thirdpart.BranchPlatformApiServiceImpl;
import com.qinyeit.serviceapp.utils.CompuUtils;
import com.qinyeit.serviceapp.utils.Lang;
import com.qinyeit.serviceapp.utils.LocalUtils;
import com.qinyeit.serviceapp.utils.SearchUtils;
import com.qinyetech.springstage.core.date.DateUtils;
import com.qinyetech.springstage.core.entity.search.SearchOperator;
import com.qinyetech.springstage.core.entity.search.Searchable;
import com.qinyetech.springstage.core.lang.QyMap;
import com.qinyetech.springstage.core.repository.jdbc.PageNamedParameterJdbcTemplate;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.qinyetech.springstage.core.service.BaseService;
import com.qinyeit.serviceapp.repository.dishes.DishesRepository;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.springframework.transaction.TransactionDefinition.PROPAGATION_REQUIRES_NEW;

/** 
 * ClassName: DishesServiceImpl <br/> 
 * Function: 商品 业务实现 <br/>
 * date: 2018-11-23 11:45:37 <br/> 
 * 
 * @author liuwenjin
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@Transactional
public class DishesServiceImpl extends BaseService<Dishes, Long> implements DishesService {


	@Autowired
	private DishesRepository dishesRepository;
	@Autowired
	private PurchaseSpecRepository purchaseSpecRepository;
	@Autowired
	private DishesSpecificationRelationRepository dishesSpecificationRelationRepository;
	@Autowired
	private DishesMakeRelationRepository dishesMakeRelationRepository;
	@Autowired
	private DishesFeedRelationRepository dishesFeedRelationRepository;
	@Autowired
	private DishesCategoryService dishesCategoryService;
	@Autowired
	private DishesUnitService dishesUnitService;
	@Autowired
	private PageNamedParameterJdbcTemplate jdbcTemplate;
	@Autowired
	private DishesPackageGroupService dishesPackageGroupService;
	@Autowired
	private DishesPackageDetailService dishesPackageDetailService;
	@Autowired
	private DishesStoreService dishesStoreService;
	@Autowired
	private MaterialService materialService;
	@Autowired
	private MaterialServiceImpl materialServiceImpl;
	@Autowired
	private MaterialCategoryService materialCategoryService;
	@Autowired
	private MaterialCostService materialCostService;
	@Autowired
	private MaterialCostDetailService materialCostDetailService;
	@Autowired
	private MaterialCostRepository materialCostRepository;
	@Autowired
	private BranchDataServiceImpl branchDataService;
	@Autowired
	private BranchPlatformApiServiceImpl branchPlatformApiService;
	@Autowired
	private DishesExtendService dishesExtendService;


//	@Transactional(propagation= Propagation.REQUIRED)
	@Override
	public QyMap saveData(JSONObject data,Long merchantGroupId) {

		JSONObject dishesData = data.getJSONObject("dishes");//商品信息
		JSONArray specData = data.getJSONArray("specs"); //规格

		JSONArray markData = data.getJSONArray("marks"); //做法
		JSONArray feedData = data.getJSONArray("feeds");//加料

		if(dishesData==null){
			throw new BusinessRunTimeException("请填写商品信息",1001);
		}

		Long id = dishesData.getLong("id");

		if(StringUtils.isBlank(dishesData.getString("no"))){
			throw new BusinessRunTimeException("请输入编码后提交",10001);
		}
		Searchable searchable = SearchUtils.buildExists(id, "no", dishesData.getString("no"),merchantGroupId);
		searchable.addSearchParam("storeId_eq",dishesData.getLong("storeId"));
		if(this.exists(searchable)){
			throw new BusinessRunTimeException("编码已经存在",10002);
		}
		if(StringUtils.isBlank(dishesData.getString("name"))){
			throw new BusinessRunTimeException("请输入名称后提交",10003);
		}
		searchable = SearchUtils.buildExists(id, "name",dishesData.getString("name"),merchantGroupId);
		searchable.addSearchParam("storeId_eq",dishesData.getLong("storeId"));
		if(this.exists(searchable)){
			throw new BusinessRunTimeException("名称已经存在",10004);
		}
		Long categoryId = dishesData.getLong("category");
		if(categoryId==null){
			throw new BusinessRunTimeException("请选择商品类别",10001);
		}
		if(StringUtils.isBlank(dishesData.getString("unit"))){
			throw new BusinessRunTimeException("请选择商品单位后提交",10002);
		}

		if(dishesData.getLong("storeId")==null){
			throw new BusinessRunTimeException("请选择商品库",10002);
		}
		if(StringUtils.isNotBlank(dishesData.getString("codes"))){
			verifyCode(dishesData.getLong("storeId"),dishesData.getString("codes"),merchantGroupId,id);
		}

		Dishes dishes = null;
		if (id!=null){
			dishes = this.findById(id);
			dishes.setUpdateTimestamp(DateUtils.current());
			//删除 规格关系 做法关系 加料关系
			dishesRepository.deleteFeeds(dishes.getId());
			dishesRepository.deleteMakes(dishes.getId());
			dishesRepository.deleteSpecs(dishes.getId());
		}else {
			dishes = new Dishes();
			dishes.setUuid(LocalUtils.getUUID());
			dishes.setUpdateTimestamp(DateUtils.current());
		}

		dishes.setMerchantGroupId(merchantGroupId);

		dishes.setCategory(dishesCategoryService.findById(categoryId));
		dishes.setName(dishesData.getString("name"));
		dishes.setNo(dishesData.getString("no"));
		dishes.setNameEn(dishesData.getString("nameEn"));
		dishes.setUnit(dishesData.getString("unit"));

		//单位不存在 添加
		searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
		searchable.addSearchParam("name_eq",dishesData.getString("unit"));
		DishesUnit unit = dishesUnitService.findOne(searchable);
		if(unit==null){
			unit = new DishesUnit();
			unit.setName(dishesData.getString("unit"));
			unit.setStoreId(dishesData.getLong("storeId"));
			dishesUnitService.save(unit);
		}
		//是否提成
		dishes.setCommission(dishesData.getBoolean("commission"));
		//提成true 提成类型
		if (dishesData.getBoolean("commission")){
			dishes.setCommissionType(DishesCommissionType.valueOf(dishesData.getString("commissionType")));
			dishes.setCommissionValue(dishesData.getDoubleValue("commissionValue"));
		}

		dishes.setFutureCost(dishesData.getDouble("futureCost"));
		dishes.setHot(dishesData.getInteger("hot"));
		dishes.setImg(dishesData.getString("img"));
		dishes.setIntroduction(dishesData.getString("introduction"));
		dishes.setPinyin(dishesData.getString("pinyin"));
		dishes.setPrice(dishesData.getDouble("price"));
//		dishes.setPrintCategoryId() //默认打印大类
		dishes.setRank(dishesData.getBoolean("rank"));
		dishes.setRecommend(dishesData.getInteger("recommend"));
		dishes.setSaleNumber(dishesData.getInteger("saleNumber"));
		dishes.setSeason(dishesData.getBoolean("season"));
		dishes.setSpell(dishesData.getString("spell"));
		dishes.setState(DishesState.valueOf(dishesData.getString("state")));
		dishes.setStoreId(dishesData.getLong("storeId"));
		dishes.setVipPrice(dishesData.getDouble("vipPrice"));
		dishes.setWeigh(dishesData.getBoolean("weigh"));


		//验证code 唯一性
//		JSONArray array = dishesData.getJSONArray("codes");
//		log.info(">>>>>>>>>>>>>>>>>>>>>>>:array:{}",array);
//		log.info(">>>>>>>>>>>>>>>>>>>>>>>:array:{}",JSON.toJSONString(array));
		/*if(CollectionUtils.isNotEmpty(array)){
			boolean boo = true;
			for (int i = 0; i < array.size(); i++) {

			}
		}
*/

		dishes.setCode(dishesData.getString("codes"));
		dishes.setBrandId(dishesData.getLong("brandId"));


		/*dishes.setExtend(dishesData.getString("extend"));
		JSONArray extend = JSON.parseArray(dishesData.getString("extend"));
		if(CollectionUtils.isNotEmpty(extend)){
			for(int i=0;i<extend.size();i++){
				JSONObject item = extend.getJSONObject(i);
				searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
				searchable.addSearchParam("storeId_eq",dishes.getStoreId());
				searchable.addSearchFilter("name", SearchOperator.eq, item.getString("name").trim());
				long count = dishesExtendService.count(searchable);
				if(count==0){
					DishesExtend dishesExtend = new DishesExtend();
					dishesExtend.setMerchantGroupId(merchantGroupId);
					dishesExtend.setStoreId(dishes.getStoreId());
					dishesExtend.setName(item.getString("name").trim());
					dishesExtendService.save(dishesExtend);
				}
			}
		}*/

		dishes = this.update(dishes);


		DishesSpecificationRelation specificationRelation = null;
		JSONObject item ;


		List<DishesSpecificationRelation> specificationRelationList = Lists.newArrayList();
		//多规格 零售、生鲜、烘焙没有多规格 原因：一个商品对应多种规格，就对应多种原料 目前采用一对一的方式
		//若使用多规格
		/**
		 * 1.商品字段 material_id 修改为字符串1,2,3
		 * 2.修改显示多规格 烘焙业态下 显示对应的几种原料的规格
		 * 3.修改删除规格关系 重新添加新的规格关系 修改对应的原料规格信息
		 * 4.
		 */


		int count = 0;
		//多规格
		if (CollectionUtils.isNotEmpty(specData)){
			if (dishes.getWeigh()){
				throw new BusinessRunTimeException("称重菜不能选择多规格",10002);
			}
			for (int i = 0; i < specData.size(); i++) {
				specificationRelation = new DishesSpecificationRelation();
				item = specData.getJSONObject(i);
				if(item.getBoolean("def")){
					dishes.setPrice(item.getDouble("price"));
					dishes.setVipPrice(item.getDouble("vipPrice"));
					count++;
				}
				specificationRelation.setDef(item.getBoolean("def"));
				specificationRelation.setVipPrice(item.getDouble("vipPrice"));
				specificationRelation.setPrice(item.getDouble("price"));
				specificationRelation.setStoreId(dishes.getStoreId());
				specificationRelation.setDishesId(dishes.getId());
				specificationRelation.setMerchantGroupId(merchantGroupId);
				specificationRelation.setSpecId(item.getLong("specId"));
				specificationRelation.setSpecName(item.getString("specName"));
				specificationRelationList.add(specificationRelation);
			}
			if(count>0 && count==1){
				dishesSpecificationRelationRepository.saveAll(specificationRelationList);
			}else {
				throw new BusinessRunTimeException("规格必须有一个默认值",10001);
			}
		}else{
			//默认规格
			specificationRelation = new DishesSpecificationRelation();
			specificationRelation.setDishesId(dishes.getId());
			specificationRelation.setStoreId(dishes.getStoreId());
			specificationRelation.setMerchantGroupId(merchantGroupId);
			specificationRelation.setDef(true);
			specificationRelation.setPrice(dishes.getPrice());
			specificationRelation.setVipPrice(dishes.getVipPrice());
			specificationRelation.setSpecName("");
			specificationRelationList.add(specificationRelation);
			dishesSpecificationRelationRepository.save(specificationRelation);
		}

		if(CompuUtils.compareTo(dishes.getPrice(),0)==0){
			throw new BusinessRunTimeException("请输入商品价格后提交",10003);
		}
		if(CompuUtils.compareTo(dishes.getVipPrice(),0)==0){
			throw new BusinessRunTimeException("请输入商品会员价格后提交",10004);
		}


		count = 0;
		//多做法
		DishesMakeRelation makeRelation = null;
		List<DishesMakeRelation> makeRelationList = Lists.newArrayList();
		if(CollectionUtils.isNotEmpty(markData)){
			for (int i = 0; i < markData.size(); i++) {
				item = markData.getJSONObject(i);
				makeRelation = new DishesMakeRelation();
				makeRelation.setStoreId(dishes.getStoreId());
				makeRelation.setDishesId(dishes.getId());
				makeRelation.setMakeCategoryId(item.getLong("makeCategoryId"));
				makeRelation.setMakeCategoryName(item.getString("makeCategoryName"));
				makeRelation.setMakeId(item.getLong("makeId"));
				makeRelation.setName(item.getString("name"));
				log.info("做法 比列類型 ： "+item.getString("priceupType"));
				makeRelation.setPriceupType(PriceupType.valueOf(item.getString("priceupType")));
				makeRelation.setVal(item.getDouble("val"));
				makeRelation.setMerchantGroupId(merchantGroupId);
				makeRelation.setDef(item.getBoolean("def"));
				if(item.getBoolean("def")){
					count++;
				}
				makeRelationList.add(makeRelation);
			}
			if(count>0 && count==1){
				dishesMakeRelationRepository.saveAll(makeRelationList);
			}else {
				throw new BusinessRunTimeException("做法必须有一个默认值",10001);
			}
		}

		//加料
		count = 0;
		DishesFeedRelation feedRelation = null;
		List<DishesFeedRelation> feedRelationList = Lists.newArrayList();
		if(CollectionUtils.isNotEmpty(feedData)){
			for (int i = 0; i < feedData.size(); i++) {
				item = feedData.getJSONObject(i);
				feedRelation = new DishesFeedRelation();
				feedRelation.setStoreId(dishes.getStoreId());
				feedRelation.setDishesId(dishes.getId());
				feedRelation.setMerchantGroupId(merchantGroupId);
				feedRelation.setCategoryId(item.getLong("categoryId"));
				feedRelation.setCategoryName(item.getString("categoryName"));
				feedRelation.setFeedId(item.getLong("feedId"));
				feedRelation.setName(item.getString("name"));
				feedRelation.setPrice(item.getDouble("price"));
				feedRelationList.add(feedRelation);
			}
			dishesFeedRelationRepository.saveAll(feedRelationList);
		}

		dishes = this.update(dishes);

		DishesStore dishesStore = dishesStoreService.findById(dishes.getStoreId());
		if (dishesStore==null){
			throw new BusinessRunTimeException("商品库不存在",10001);
		}


		QyMap map = QyMap.map("id",dishes.getId());
		map.setv("flag",false);
		//行业是烘焙 生鲜 零售 没有多规格
		if(dishesStore.getIndustry()==Industries.HB || dishesStore.getIndustry()==Industries.LS || dishesStore.getIndustry()==Industries.SX){
			//新增或者修改原料类别
			MaterialCategory category = updateMaterialCategory(merchantGroupId, dishes);


			QyMap itemMap = saveForHBData(dishes,data,merchantGroupId,category);
			//将原料id保存在商品中
			Material material = itemMap.getAs("material",Material.class);
			dishes.setMaterialId(material.getId());
			dishes = this.update(dishes);
			//保存成本卡 1：1
			saveCostCard(material,dishes,merchantGroupId);
			map.setv("material_id",material.getId())
					.setv("category_id",category.getId());
			map.setv("flag",true);
			map.setv("ids",itemMap.get("ids"));
		}

		log.info("baocun chenggong ");
		return map;
	}

	private MaterialCategory updateMaterialCategory(Long merchantGroupId, Dishes dishes) {
		Searchable searchable;//将商品类别保存到原料类别中 根据类别id 判断有没有，没有就保存 有就修改
		searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
		searchable.addSearchParam("dishesCategoryId_eq",dishes.getCategory().getId());
		MaterialCategory category = materialCategoryService.findOne(searchable);
		if(category==null){
            category = new MaterialCategory();
            category.setStoreId(dishes.getStoreId());
            category.setUuid(dishes.getCategory().getUuid());
            category.setDishesCategoryId(dishes.getCategory().getId());
            category.setMerchantGroupId(merchantGroupId);
        }
		category.setNo(dishes.getCategory().getNo());
		category.setUpdateTimestamp(dishes.getCategory().getUpdateTimestamp());
		category.setName("S"+dishes.getCategory().getName());
		category.setParentId(0L);
		category.setParentIds("0/");
		if(category.getId()==null){
            materialCategoryService.save(category);
        }else {
            materialCategoryService.update(category);
        }
		return category;
	}

	/**
	 * 烘焙类型
	 * 	1.保存商品-原料 1:1
	 * 	2.成本卡 1:1
	 * @param dishes
	 * @param data
	 * return 原料ids
	 */
	private QyMap saveForHBData(Dishes dishes, JSONObject data,Long merchantGroupId,MaterialCategory category) {
		JSONObject stockForm = data.getJSONObject("stockForm"); //库存信息
		JSONArray purchaseJson = data.getJSONArray("purchase"); //多采购规格
		Material material = null;


		category=materialCategoryService.findById(category.getId());


		//查询所有成品原料
		if(dishes.getMaterialId()==null){
			//新建
			material = new Material();
			String no = materialService.getNextNo("10001",merchantGroupId);
			material.setNo(no);
			material.setMerchantGroupId(merchantGroupId);
			material.setUuid(dishes.getUuid());

		}else {
			//编辑
			material = materialService.findById(dishes.getMaterialId());
			purchaseSpecRepository.deleteByMaterialId(material.getId());
		}

		material.setName(dishes.getName());
		material.setUpdateTimestamp(dishes.getUpdateTimestamp());
		material.setCategory(null);
		material.setConsumeRates(1d);
		material.setConsumeUnit(dishes.getUnit());
		material.setGoodsSpec(stockForm.getString("goodsSpec"));
		material.setMaxStock(stockForm.getDouble("maxStock"));
		material.setMinStock(stockForm.getDouble("minStock"));
		material.setOrderPriceBom(dishes.getFutureCost());
		material.setOrderType(OrderType.valueOf(stockForm.getString("orderType")));
		material.setPinyin(dishes.getPinyin());
		material.setSpell(dishes.getSpell());
		material.setState(State.NORMAL);
		material.setStocktakeType(InventoryType.valueOf(stockForm.getString("stocktakeType")));
		material.setStoreMode(StoreMode.valueOf(stockForm.getString("storeMode")));
		material.setUnit(dishes.getUnit());
		material.setMaterialType(MaterialType.PRODUCT);
		material.setMerchantGroupId(merchantGroupId);
		material.setStoreId(dishes.getStoreId());
		material.setCode("");
		//多条码
		if(StringUtils.isNotBlank(dishes.getCode())){
			List<String> codeList = JSON.parseArray(dishes.getCode(),String.class);
			if(CollectionUtils.isNotEmpty(codeList)){
				String codes = StringUtils.join(codeList, ",");
				if(StringUtils.isNotBlank(codes)){
					material.setCode(","+codes+",");
				}
			}
		}
//

		material = materialService.update(material);
		//material.setCategory(category);


		//保存多采购规格
		if(CollectionUtils.isEmpty(purchaseJson)){
			throw new BusinessRunTimeException("采购规格至少保留一条",10001);
		}
		//保存多采购规格
		QyMap item = materialService.savePurchaseSpecs(merchantGroupId, material, purchaseJson);
		QyMap map = QyMap.map("ids",item.getList("ids",Long.class));
		map.setv("material",material);
		return map;

	}

	/**
	 * 保存原料 中的 原料类别
	 * @param categoryId
	 * @param materialId
	 */
	public void saveMaterialForCategory(Long categoryId, Long materialId) {
		String sql= "update materials set category_id=:category_id where id=:id";
		jdbcTemplate.update(sql, QyMap.map("category_id",categoryId).setv("id",materialId));
	}

	/**
	 * 保存成本卡 商品 - 原料 1:1
	 * @param material
	 * @param dishes
	 * @param merchantGroupId
	 */
	private void saveCostCard(Material material, Dishes dishes, Long merchantGroupId) {

		Searchable searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
		searchable.addSearchParam("storeId_eq",dishes.getStoreId());
		searchable.addSearchParam("dishesId_eq",dishes.getId());
		MaterialCost materialCost = materialCostService.findOne(searchable);
		if(materialCost==null){
			materialCost = new MaterialCost();
			materialCost.setUuid(LocalUtils.getUUID());
			materialCost.setUpdateTimestamp(DateUtils.current());
			materialCost.setStoreId(dishes.getStoreId());
			materialCost.setMerchantGroupId(merchantGroupId);
		}else {
			//删除成本卡明细
			materialCostRepository.deleteByCostId(materialCost.getId());
		}
		materialCost.setDishesId(dishes.getId());
		//理论金额  | 原料成本
		//消耗数量*成本卡标准价/消耗单位换算值
		double cost = 1*material.getOrderPriceBom()/material.getConsumeRates();
		materialCost.setCost(cost);
		materialCost.setMaterialCost(cost);
		materialCost.setOtherCost(0d);
		materialCost.setProcessQty(1);
		materialCostService.update(materialCost);

		MaterialCostDetail materialCostDetail = new MaterialCostDetail();
		materialCostDetail.setMerchantGroupId(merchantGroupId);
		materialCostDetail.setCost(materialCost);
		materialCostDetail.setExpend(1d);
		materialCostDetail.setMaterialId(material.getId());
		materialCostDetail.setPrincipal(true);

		materialCostDetailService.update(materialCostDetail);
		//保存成本卡 end
		log.info("保存成本卡 end ");
	}

	@Override
	public Page<Map<String, Object>> getDishesData(Long merchantGroupId, Long storeId, Long categoryId, String name,Searchable searchable) {
		String sql = "SELECT s.spec_id, s.spec_name, s.price, s.vip_price, s.def\n" +
				"\t, s.dishes_id, d.name, d.no, d.category_id, d.id\n" +
				"\t, c.name AS category_name\n" +
				"FROM dishes_specification_relations s\n" +
				"\tLEFT JOIN dishess d ON d.id = s.dishes_id\n" +
				"\tLEFT JOIN dishes_categorys c ON c.id = d.category_id\n" +
				"WHERE s.is_deleted = 0 \n" +
				"\tAND s.merchant_group_id = :merchantGroupId\n" +
				"\tAND d.is_deleted = 0 and d.store_id = :storeId and d.type='DISHES'\n" ;

		QyMap map = QyMap.map("merchantGroupId",merchantGroupId)
				.setv("storeId",storeId);
		if(StringUtils.isNotBlank(name)){
			sql += 	" AND (d.name LIKE :name OR d.no LIKE :name) " ;
			map.setv("name","%"+name+"%");
		}
		if (categoryId!=null){
			sql += " AND c.id = :categoryId";
			map.setv("categoryId",categoryId);
		}
		Page<Map<String,Object>> mapPage = jdbcTemplate.queryForList(sql,map,searchable.getPage());
		return mapPage;
	}

	@Override
	public void savePackageData(JSONObject data, Long merchantGroupId) {



		JSONObject packageData = data.getJSONObject("packages");
		JSONArray dishesData = data.getJSONArray("selectDishes");
		if(packageData==null){
			throw new BusinessRunTimeException("请填写套餐信息，套餐信息不能为空",10001);
		}
		if(CollectionUtils.isEmpty(dishesData)){
			throw new BusinessRunTimeException("请选择商品",10002);
		}
		Long id = packageData.getLong("id");
		Long storeId = packageData.getLong("storeId");
		Searchable searchable = SearchUtils.buildExists(id, "name",packageData.getString("name"),merchantGroupId );
		searchable.addSearchParam("storeId_eq",storeId);
		searchable.addSearchParam("type_eq",DishesType.PACKAGE);
		if(this.exists(searchable)){
			throw new BusinessRunTimeException("名称已经存在",10002);
		}

		Dishes dishes = null;
		if(id!=null){
			dishes = this.findById(id);
			dishes.setUpdateTimestamp(DateUtils.current());
			delPackages(id);
		}else {
			dishes = new Dishes();
			dishes.setUuid(LocalUtils.getUUID());
			dishes.setUpdateTimestamp(DateUtils.current());
		}


		dishes.setMerchantGroupId(merchantGroupId);
		searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
		searchable.addSearchParam("storeId_eq",storeId);
		searchable.addSearchParam("no_eq","00000");
		DishesCategory category = dishesCategoryService.findOne(searchable);
		if(category==null){
			throw new BusinessRunTimeException("套餐类别为空",10002);
		}
		if (packageData.getLong("storeId")==null){
			throw new BusinessRunTimeException("请选择商品库",1001);
		}
		dishes.setCategory(category);
		dishes.setType(DishesType.PACKAGE);
		dishes.setName(packageData.getString("name"));
		dishes.setNo(packageData.getString("no"));
		dishes.setNameEn(packageData.getString("nameEn"));
		dishes.setHot(packageData.getInteger("hot"));
		dishes.setImg(packageData.getString("img"));
		dishes.setIntroduction(packageData.getString("introduction"));
		dishes.setPinyin(packageData.getString("pinyin"));
		dishes.setPrice(packageData.getDouble("price"));
		dishes.setRank(packageData.getBoolean("rank"));
		dishes.setRecommend(packageData.getInteger("recommend"));
		dishes.setSpell(packageData.getString("spell"));

		dishes.setStoreId(packageData.getLong("storeId"));
		dishes.setVipPrice(packageData.getDouble("vipPrice"));
		dishes.setPackType(PackageType.valueOf(packageData.getString("packType")));
		if(dishes.getPackType()==PackageType.EASYPACKAGE){ //简易套餐的价格类型为固定价格
			dishes.setPriceMode(PriceMode.FIXEDPRICE);
		}else {
			dishes.setPriceMode(PriceMode.valueOf(packageData.getString("priceMode")));
		}

		dishes = this.update(dishes);

		//简易套餐 在规格关系中存储一份数据
		if(dishes.getPackType()==PackageType.EASYPACKAGE){
			DishesSpecificationRelation dishesSpecificationRelation = new DishesSpecificationRelation();
			dishesSpecificationRelation.setDishesId(dishes.getId());
			dishesSpecificationRelation.setPrice(dishes.getPrice());
			dishesSpecificationRelation.setVipPrice(dishes.getVipPrice());
			dishesSpecificationRelation.setDef(true);
			dishesSpecificationRelation.setMerchantGroupId(merchantGroupId);
			dishesSpecificationRelation.setStoreId(storeId);
			dishesSpecificationRelationRepository.save(dishesSpecificationRelation);
		}
		//套餐组
		JSONObject item ;
		JSONObject deItem ;
		DishesPackageGroup group = null;
		DishesPackageDetail detail = null;
		JSONArray details = null;
		//套餐组
		int count = 0;
		for (int i = 0; i < dishesData.size(); i++) {
			item = dishesData.getJSONObject(i);
			if(CollectionUtils.isEmpty(item.getJSONArray("details"))){
				throw new BusinessRunTimeException("请选择商品明细",10001);
			}
			details = item.getJSONArray("details");
			group = new DishesPackageGroup();
			group.setMerchantGroupId(merchantGroupId);
			group.setPackId(dishes.getId());
			if(dishes.getPackType()==PackageType.EASYPACKAGE){
				group.setTotal(item.getInteger("total"));
				group.setCount(1);
				group.setHasRepeat(false);
			}else if (dishes.getPackType()==PackageType.SELECTPACKAGE){
				group.setTotal(item.getJSONArray("details").size());
				group.setCount(item.getInteger("count"));
				group.setHasRepeat(item.getBoolean("hasRepeat"));
			}else {
				group.setTotal(item.getInteger("total"));
				group.setCount(item.getInteger("count"));
				group.setHasRepeat(item.getBoolean("hasRepeat"));
			}
			group.setName(item.getString("name"));
			group = dishesPackageGroupService.save(group);
			count = 0;
			for (int n = 0; n < details.size(); n++) {

				deItem = details.getJSONObject(n);

				detail = new DishesPackageDetail();
				if(dishes.getPackType()==PackageType.EASYPACKAGE){
					if(deItem.getBoolean("def")){
//						group.setName(this.findById(deItem.getLong("dishesId")).getName());
						count++;
					}
				}else if(dishes.getPackType()==PackageType.COMBINATIONPACKAGE){

				}
				detail.setGroupId(group.getId());
				detail.setAlternative(deItem.getBoolean("alternative"));
				detail.setCount(deItem.getDouble("count"));
				detail.setDef(deItem.getBoolean("def"));
				detail.setDiff(deItem.getDouble("diff"));
				detail.setDishesId(deItem.getLong("dishesId"));
				detail.setPackId(dishes.getId());
				detail.setSpecId(deItem.getLong("specId"));
				detail.setSpecName(deItem.getString("specName"));
				detail.setPrice(deItem.getDouble("price"));
				detail.setMerchantGroupId(merchantGroupId);
				dishesPackageDetailService.save(detail);
			}
			if(dishes.getPackType()==PackageType.EASYPACKAGE){

				if(count!=1){
					throw new BusinessRunTimeException("简易套餐组合只能有一个默认商品",10001);
				}
			}

		}


	}

	@Override
	public List<Map<String, Object>> getPackDetails(Dishes dishes) {
		String sql="SELECT " +
				" r.id,pd.dishes_id as dishesId , " +
				" pd.spec_id as guigeId , " +
				" pd.diff as difference, " +
				" pd.def as def, " +
				" pd.alternative as isAlternative," +
				" pd.count as number, " +
				" d.name as name," +
				" p.name as guige, " +
				" g.id as groupId," +
				" IFNULL(r.price,0) AS price, " +
				" IFNULL(r.vip_price, 0) AS vipPrice,g.id as disheGroupId " +
				" FROM dishes_package_details pd  " +
				" LEFT JOIN dishess d ON pd.dishes_id=d.id " +
				" LEFT JOIN dishes_specifications p ON pd.spec_id=p.id " +
				" LEFT JOIN dishes_package_groups g ON g.id=pd.group_id " +
				" LEFT JOIN dishes_specification_relations r ON d.id=r.dishes_id AND (p.id=r.spec_id OR (r.spec_id IS NULL)) "+
				" WHERE g.pack_id=:packId order by g.id ASC,d.id ASC ";
		QyMap map = QyMap.map("packId",dishes.getId());
		return jdbcTemplate.queryForList(sql,map);
	}

	@Override
	public void deletedPackageDetails(Long id) {
		delPackages(id);
	}

	@Override
	public void deletedMaterialCostDetails(Long id) {
		dishesRepository.deleteSpecs(id);
		dishesRepository.deleteMakes(id);
		dishesRepository.deleteFeeds(id);
		Long[] detailIds=dishesRepository.findByCostDetailsId(id);
		if (ArrayUtils.isNotEmpty(detailIds)){
			dishesRepository.deleteCostDetailsByIds(detailIds);
		}
		dishesRepository.deleteCostByDishes(id);
	}

	@Override
	public String getNextNo(DishesType type, String def,Long merchantGroupId) {
		String sql = "SELECT * from dishess where merchant_group_id = :merchant_group_id and is_deleted = false and type=:type ORDER BY id DESC LIMIT 1";
		QyMap param = QyMap.map("merchant_group_id",merchantGroupId)
				.setv("type",type.getKey());
		List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql,param);
		if(CollectionUtils.isNotEmpty(maps)){
			Map<String, Object> map = maps.get(0);
			if(map.containsKey("no")){
				String lastNo = map.get("no").toString();
				return Lang.getNextNo(lastNo);
			}
		}
		return def;
	}

	@Override
	public void deleteBranchDishesData(Dishes dishes) {
		branchDataService.deleteBranchDishesData(dishes);
	}

    @Override
    public List<Map<String, Object>> getDishesBranchs( Long id) {
		Dishes dishes = this.findById(id);
		if (dishes==null){
			return null;
		}
		return branchDataService.getDishesBranchs(id,dishes);
    }

	@Override
	public boolean deleteBranchDishesData(String uuid) {
		if (StringUtils.isBlank(uuid)){
			return false;
		}
		return branchPlatformApiService.deleteBranchDishesData(uuid);
	}

	@Transactional(propagation=Propagation.NOT_SUPPORTED) //FIXME 暂时不知道为什么在这里使用事务
	@Override
	public void saveStoreTestInfos(Long storeId, Long merchantGroupId) {
		if(storeId==null || merchantGroupId==null){
			return ;
		}

		String sql = "select * from test_goods";

		List<Map<String,Object>> mapList = jdbcTemplate.queryForList(sql,QyMap.NEW());
		if(CollectionUtils.isEmpty(mapList)){
			return;
		}
		QyMap item = null;
		//判断商品库类型
		DishesStore dishesStore = dishesStoreService.findById(storeId);
		if(dishesStore==null){
			return;
		}
		if(dishesStore.getIndustry()==Industries.LS){
			/**
			 * 1.商品类别 判断查询有 直接保存 没有 添加商品类别再保存  判断原料类别有没有 有 保存 没有 原料类别 保存 再添加
			 * 2.商品单位 判断查询有 直接保存 没有 添加商品单位再保存
			 * 3.保存信息 商品信息
			 * 4.保存商品信息和保存对应的成品原料信息 商品信息字段的原料id(material_id)保存
			 * 5.成本卡和成本卡明细 1：1
			 * 6.商品规格默认添加一条（dishesSpecRelation）
			 * 7.原料采购规格 默认添加一条 与商品单位1:1的
			 *
			 */
			Dishes dishes = null;
			DishesCategory dishesCategory=null;
			MaterialCategory materialCategory=null;
			Material material=null;

			List<String> codeList = null;
			int index = 0;
			for (Map<String, Object> objectMap : mapList) {
				index++;
				log.info("index >>>>>>>>>>> : {}",index);

				codeList = Lists.newArrayList();
				item = QyMap.WRAP(objectMap);
				dishes = new Dishes();

				/*保存商品类别   判断查询有 直接保存 没有 添加商品类别再保存 */
				Searchable searchable;
				searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
				searchable.addSearchParam("name_eq",item.getString("category_name"));
				searchable.addSearchParam("storeId_eq",storeId);
				dishesCategory = dishesCategoryService.findOne(searchable);
				if(dishesCategory==null){
					dishesCategory = new DishesCategory();
					dishesCategory.setName(item.getString("category_name"));
					dishesCategory.setStoreId(storeId);
					dishesCategory.setNo(item.getString("category_no"));
					dishesCategory.setUuid(LocalUtils.getUUID());
					dishesCategory.setMerchantGroupId(merchantGroupId);
					dishesCategory.setUpdateTimestamp(DateUtils.current());
					dishesCategory = dishesCategoryService.save(dishesCategory);
				}


				/*保存原料类别*/
				searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
				searchable.addSearchParam("name_eq",item.getString("category_name"));
				searchable.addSearchParam("storeId_eq",storeId);
				materialCategory=materialCategoryService.findOne(searchable);
				if(materialCategory==null){
					materialCategory = new MaterialCategory();
					materialCategory.setMerchantGroupId(merchantGroupId);
					materialCategory.setName(item.getString("category_name"));
					materialCategory.setStoreId(storeId);
					materialCategory.setDishesCategoryId(dishesCategory.getId());
					materialCategory.setUuid(dishesCategory.getUuid());
					materialCategory.setUpdateTimestamp(dishesCategory.getUpdateTimestamp());
					materialCategory.setNo("S"+dishesCategory.getNo());
					materialCategory = materialCategoryService.save(materialCategory);
				}
				/*保存单位*/
				DishesUnit dishesUnit=null;
				boolean boo = dishesUnitService.exists(SearchUtils.buildExists(null, "name", item.getString("unit"),merchantGroupId));
				if(!boo){
					//不存在 保存单位
					dishesUnit = new DishesUnit();
					dishesUnit.setName(item.getString("unit"));
					dishesUnit.setState(State.NORMAL);
					dishesUnit.setUuid(LocalUtils.getUUID());
					dishesUnit.setUpdateTimestamp(DateUtils.current());
					dishesUnit.setMerchantGroupId(merchantGroupId);
					dishesUnit.setStoreId(storeId);
					dishesUnit = dishesUnitService.save(dishesUnit);
				}

				/*保存商品信息*/
				dishes.setCode(JSON.toJSONString(codeList));
				codeList.add(item.getString("code"));
				dishes.setUuid(LocalUtils.getUUID());
				dishes.setUpdateTimestamp(DateUtils.current());
				dishes.setMerchantGroupId(merchantGroupId);

				dishes.setCategory(dishesCategory);
				dishes.setName(item.getString("name"));
				dishes.setNo(item.getString("no"));
				dishes.setUnit(item.getString("unit"));
				dishes.setFutureCost(item.getDouble("cost_price"));
				dishes.setPrice(item.getDouble("sell_price"));
				dishes.setStoreId(storeId);
				dishes.setVipPrice(item.getDouble("sell_price"));
				if(item.getInt("weigh")==2){
					dishes.setWeigh(true);
				}
				dishes = this.save(dishes);
				System.out.println(">>>>>>>>>1");
				/*保存原料*/
				material = new Material();
				String no = materialService.getNextNo("10001",merchantGroupId);
				material.setNo(no);
				material.setMerchantGroupId(merchantGroupId);
				material.setUuid(dishes.getUuid());
				material.setName(dishes.getName());
				material.setUpdateTimestamp(dishes.getUpdateTimestamp());
				material.setCategory(materialCategory);
				material.setConsumeRates(1d);
				material.setConsumeUnit(dishes.getUnit());
				material.setOrderPriceBom(dishes.getFutureCost());
				material.setPinyin(dishes.getPinyin());
				material.setSpell(dishes.getSpell());
				material.setState(State.NORMAL);
				material.setUnit(dishes.getUnit());
				material.setMaterialType(MaterialType.PRODUCT);
				material.setMerchantGroupId(merchantGroupId);
				material.setStoreId(dishes.getStoreId());
				material = materialService.save(material);
				System.out.println(">>>>>>>>>2");
				/*将原料id保存进商品中*/
				dishes.setMaterialId(material.getId());
				dishes = this.update(dishes);
				System.out.println(">>>>>>>>>3");

				//保存成本卡 1：1
				saveCostCard(material,dishes,merchantGroupId);
				System.out.println(">>>>>>>>>4");

				/*保存商品规格*/
				//默认规格
				DishesSpecificationRelation specificationRelation = new DishesSpecificationRelation();
				specificationRelation.setDishesId(dishes.getId());
				specificationRelation.setStoreId(dishes.getStoreId());
				specificationRelation.setMerchantGroupId(merchantGroupId);
				specificationRelation.setDef(true);
				specificationRelation.setPrice(dishes.getPrice());
				specificationRelation.setVipPrice(dishes.getVipPrice());
				specificationRelation.setSpecName("");
				dishesSpecificationRelationRepository.save(specificationRelation);
				System.out.println(">>>>>>>>>5");

				/*保存一条采购规格*/
				PurchaseSpec purchaseSpec=new PurchaseSpec();
				purchaseSpec.setMerchantGroupId(material.getMerchantGroupId());
				purchaseSpec.setMaterial(material);
				purchaseSpec.setName(item.getString("unit"));
				purchaseSpec.setPrice(0d);
				purchaseSpec.setHasDef(true);
				purchaseSpec.setUnit(item.getString("unit"));
				purchaseSpecRepository.save(purchaseSpec);
				System.out.println(">>>>>>>>>6");
			}
			System.out.println(">>>>>>>>>1111111");
		}

		System.out.println(">>>>>>>>>test");

	}

	@Override
	public boolean verifyCode(Long storeId, String code, Long merchantGroupId,Long dishesId) {
		if(storeId==null || StringUtils.isBlank(code) || merchantGroupId==null){
			throw new BusinessRunTimeException("参数错误",2001);
		}
		//本次添加/修改的商品条码
		List<String> codes = JSON.parseArray(code,String.class);
		if(CollectionUtils.isEmpty(codes)){
			//条码为空 不做判断
			return true;
		}
		//本次添加的条码是否有重复
		long recount = codes.stream().distinct().count();
		boolean isRepeat = recount<codes.size();
		//商品中的条码重复
		if(isRepeat){
			throw new BusinessRunTimeException("商品中条码含有重复，请检查",10001);
		}
		//本次商品不存在重复 则判断该条码中在本商品库中是否存在
		String sql = "";
		QyMap map = null;
		for (String s : codes) {
			sql = "SELECT count(*) as count FROM dishess WHERE length(code)>0 and JSON_SEARCH(code,'one',:code) IS NOT NULL and store_id = :store_id and merchant_group_id = :merchant_group_id ";
//			sql = "SELECT count(*) as count FROM dishess WHERE code LIKE :code and store_id = :store_id and merchant_group_id = :merchant_group_id ";
			map = QyMap.map("code",s)
					.setv("store_id",storeId)
					.setv("merchant_group_id",merchantGroupId);
			if(dishesId!=null){
				//编辑 排除本商品的条码
				sql += " and id !=:id";
				map.setv("id",dishesId);
			}
			long count = jdbcTemplate.queryForScalar(sql,map,Long.class);
			if(count>0){
				throw new BusinessRunTimeException("商品条码["+s+"]已存在",10002);
			}
		}
		return true;
	}


	/**
	 * 删除套餐组 和套餐明细 和 规格
	 * @param dishesId
	 */
	private void delPackages(Long dishesId) {
		dishesRepository.deleteSpecs(dishesId);
		Long[] groupIds=dishesRepository.findByPackId(dishesId);
		dishesRepository.deletePackageDetailsByPackageIds(groupIds);
		dishesRepository.deletePackageGroupByDishes(dishesId);
	}
}